package com.liuzy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import com.dd.plist.NSDictionary;
import com.dd.plist.NSString;
import com.dd.plist.PropertyListParser;

public class IpaDecoder {
	public static void main(String[] args) throws Exception {
		File ipa = new File("d:\\test\\sqfengchao.ipa");
		decode(ipa);
//		writeXml(ipa);
	}

	/**
	 * 解析IPA文件，并导出XML
	 */
	public static void writeXml(File ipa) throws Exception {
		File file = getFile(ipa);
		NSDictionary rootDict = (NSDictionary) PropertyListParser.parse(file);
		String plistStr = rootDict.toXMLPropertyList();
		FileOutputStream plistOut = new FileOutputStream(new File(ipa.getParent() + File.separator + "info.plist"));
		plistOut.write(plistStr.getBytes());
		plistOut.close();
		file.delete();
		file.getParentFile().delete();
	}

	/**
	 * 解析IPA文件，读取版本等信息
	 */
	public static Result decode(File ipa) throws Exception {
		Result result = new Result();
		File file = getFile(ipa);
		NSDictionary rootDict = (NSDictionary) PropertyListParser.parse(file);
		result.setAppName(getValue(rootDict, "CFBundleName"));
		result.setPackageName(getValue(rootDict, "CFBundleIdentifier"));
		result.setVersion(getValue(rootDict, "CFBundleShortVersionString"));
		file.delete();
		file.getParentFile().delete();
		System.out.println(result);
		return result;
	}

	private static String getValue(NSDictionary dict, String Key) {
		NSString value = (NSString) dict.objectForKey(Key);
		return value == null ? "" : value.toString();
	}

	/**
	 * IPA文件的拷贝，把一个IPA文件复制为Zip文件,同时返回Info.plist文件
	 */
	private static File getFile(File ipa) throws Exception {
		String zipFileName = ipa.getAbsolutePath().replaceAll(".ipa", ".zip");
		File zip = new File(zipFileName);
		InputStream ipaIn = new FileInputStream(ipa);
		FileOutputStream zipOut = new FileOutputStream(zip);
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = ipaIn.read(buffer)) != -1) {
			zipOut.write(buffer, 0, len);
		}
		if (ipaIn != null) {
			ipaIn.close();
		}
		if (zipOut != null) {
			zipOut.close();
		}
		// 获取Info.plist文件存储指定位置
		InputStream zipIn = null;
		OutputStream plistOut = null;
		File plistFile = null;
		File unzipFile = null;
		ZipFile zipFile = null;
		try {
			// 创建zip文件对象
			zipFile = new ZipFile(zip);
			// 创建本zip文件解压目录
			String name = zip.getName().substring(0, zip.getName().lastIndexOf("."));
			unzipFile = new File(zip.getParent() + "/" + name);
			if (unzipFile.exists()) {
				unzipFile.delete();
			}
			unzipFile.mkdir();
			// 得到zip文件条目枚举对象
			Enumeration<? extends ZipEntry> zipEnum = zipFile.entries();
			// 定义对象
			ZipEntry entry = null;
			String entryName = null;
			String names[] = null;
			// 循环读取条目
			while (zipEnum.hasMoreElements()) {
				// 得到当前条目
				entry = zipEnum.nextElement();
				entryName = new String(entry.getName());
				// 用/分隔条目名称
				names = entryName.split("\\/");
				for (int i = 0; i < names.length; i++) {
					if (entryName.endsWith(".app/Info.plist")) { // 为Info.plist文件,则输出到文件
						zipIn = zipFile.getInputStream(entry);
						plistFile = new File(unzipFile.getAbsolutePath() + "/Info.plist");
						plistOut = new FileOutputStream(plistFile);
						buffer = new byte[1024 * 8];
						int readLen = 0;
						while ((readLen = zipIn.read(buffer, 0, 1024 * 8)) != -1) {
							plistOut.write(buffer, 0, readLen);
						}
						break;
					}
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			if (zipIn != null)
				zipIn.close();
			if (plistOut != null) {
				plistOut.flush();
				plistOut.close();
			}
			// 必须关流，否则文件无法删除
			if (zipFile != null) {
				zipFile.close();
			}
		}
		// 如果有必要删除多余的文件
		if (zip.exists()) {
			zip.delete();
		}
		return plistFile;
	}

}
